﻿/******************************************************************************
 * 【本类功能概述】                                 					      *
 *  版权所有（C）2017- 匠梦科技                                         *
 *  保留所有权利。                                                            *
 ******************************************************************************
 *  作者 : <hughjk>
 *  创建时间:2020年2月25日 11:37:48
 *  文件描述: TimeLine 关闭执行线,与开启
 *****************************************************************************/

using System.Linq;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Audio;
using UnityEngine.Playables;
using Object = UnityEngine.Object;

public class TimeLineRuntimeMuter : Singleton<TimeLineRuntimeMuter>
{
    public string trackName;

    private int trackIndex = -1;
    private Object trackToMute;
    public PlayableDirector playableDirector;

    public void Mute(string _trackName)
    {
        trackName = _trackName;
        FindTrack();
        Mute();
    }

    public void Mute(int _trackIndex)
    {
        trackIndex = _trackIndex;
        Mute();
    }

    public void UnMute(string _trackName)
    {
        trackName = _trackName;
        FindTrack();
        UnMute();
    }

    public void UnMute(int _trackIndex)
    {
        trackIndex = _trackIndex;
        IdFindTrack();
        UnMute();
    }

    private void FindTrack()
    {
        if (playableDirector != null && playableDirector.playableAsset != null)
        {
            trackIndex = -1;
            var bindings = playableDirector.playableAsset.outputs.ToArray();
            for (int i = 0; i < bindings.Length; i++)
            {
                if (bindings[i].streamName == trackName)
                {
                    trackToMute = bindings[i].sourceObject;
                    trackIndex = i;
                    break;
                }
            }
            if (trackIndex == -1)
            {
                debug.log("Binding 名字:", trackName, "不存在 !!!");
            }
        }
    }

    private void IdFindTrack()
    {
        if (playableDirector != null && playableDirector.playableAsset != null)
        {
            var bindings = playableDirector.playableAsset.outputs.ToArray();
            if (bindings.Length > trackIndex && trackIndex > 0)
            {
                trackToMute = bindings[trackIndex].sourceObject;
            }
            else
            {
                debug.log("TrackIndex :", trackIndex, " 错误!!! 下标从1开始");
            }
        }
    }

    private void Mute()
    {
        if (trackIndex == -1)
            return;

        var graph = playableDirector.playableGraph;
        if (!graph.IsValid())
            return;

        PlayableOutput output = graph.GetOutput(trackIndex);
        if (output.IsPlayableOutputOfType<AnimationPlayableOutput>())
        {
            ((AnimationPlayableOutput)output).SetTarget(null);
        }
        else if (output.IsPlayableOutputOfType<AudioPlayableOutput>())
        {
            ((AudioPlayableOutput)output).SetTarget(null);
        }
        else
        {
            output.SetUserData(null);
        }
    }

    private void UnMute()
    {
        if (trackIndex == -1)
            return;

        var graph = playableDirector.playableGraph;
        if (!graph.IsValid())
            return;

        PlayableOutput output = graph.GetOutput(trackIndex);
        var binding = playableDirector.GetGenericBinding(trackToMute);
        if (output.IsPlayableOutputOfType<AnimationPlayableOutput>())
        {
            var animator = binding as Animator;
            if (animator == null && binding is GameObject)
                animator = (binding as GameObject).GetComponent<Animator>();
            ((AnimationPlayableOutput)output).SetTarget(animator);
        }
        else if (output.IsPlayableOutputOfType<AudioPlayableOutput>())
        {
            var audioSource = binding as AudioSource;
            if (audioSource == null && binding is GameObject)
                audioSource = (binding as GameObject).GetComponent<AudioSource>();
            ((AudioPlayableOutput)output).SetTarget(audioSource);
        }
        else
        {
            output.SetUserData(binding);
        }
    }
}